﻿using System;
using System.Collections.Generic;
using System.Text;
using IBLL;
using Model.WebService;

using System.Data;
using Common.Logging;
using Model.Task;
using AppToolKit.Data;
using AppToolKit.Core.Context.Spring;
using Model;
using System.Text.RegularExpressions;
using Utility;

using BLL.Action.Core.Caching;
using BLL.Action.Core.State;
using BLL.Action.Core.Macro;


namespace BLL.Action.Core.Base
{
    public abstract class ActionBase:IAction
    {
             
        #region  属性
        //ILog log = LogManager.GetLogger(LogDefault.AppInfo);
        //ILog logError = LogManager.GetLogger(LogDefault.AppError);

        protected abstract ITransfer TransferHolder { get; }
         
      
        [AutoWiring]
        public ClientCache Cache { get; set; }

        protected abstract IActionBusiness ActionBusinessHolder { get; }
        //{
        //    get {
        //        ActionBusiness actionBusiness = new ActionBusiness();
        //        ContextAwareHolder.AutowireObject(actionBusiness);
        //        return actionBusiness;
        //    }
        //}

        [AutoWiring]
        public IDbProcessor DbProcessor { get; set; }

        [AutoWiring]
        public ContextAware ContextAwareHolder { get; set; }

        [AutoWiring]
        public StateMonitor StateMonitorholder { get; set; }

        protected Dictionary<string, Queue<TaskDefine>> queueDict;
        #endregion 
       
        #region IAction 成员
      
        public virtual void Execute(object p)
        {
            try
            {
                LogHelper.GetDebugLog().Debug("start action");

                TaskDefine task = p as TaskDefine;

                LogHelper.GetDebugLog().Debug(string.Format("hotelid:{0},{1}", string.Format("{0}_{1}", "QueueObject", task.Hotelid), task.Interface));
                LogHelper.GetDebugLog().Debug("start tranfer");
                queueDict = CacheHelper.Cache(Cache, string.Format("{0}_{1}", CacheConst.HotelTask, task.Hotelid), delegate { return GetQueue(); }) as Dictionary<string, Queue<TaskDefine>>;
                AddQueue(task);
                LogHelper.GetDebugLog().Debug(string.Format("calc queue count:{0},{1}", queueDict[task.Hotelid].Count, task.Hotelid));
                StateMonitorholder.WirteNormalLog(task.Hotelid, "");

               object obj= CacheHelper.GetCache(Cache, string.Format("{0}_{1}_{2}", CacheConst.HotelTask, task.Hotelid, "isRun"));
                if (obj==null)
                {
                    CacheHelper.Cache(Cache, string.Format("{0}_{1}_{2}", CacheConst.HotelTask, task.Hotelid, "isRun"), delegate { return GetState(); });
                    LogHelper.GetDebugLog().Debug(string.Format("add cache :{0},{1}", task.Hotelid, string.Format("{0}_{1}_{2}", CacheConst.HotelTask, task.Hotelid, "isRun")));
                    ExecuteQueue(queueDict[task.Hotelid]);
                    CacheHelper.RemoveCache(Cache, string.Format("{0}_{1}_{2}", CacheConst.HotelTask, task.Hotelid, "isRun"));
                    LogHelper.GetDebugLog().Debug(string.Format("remove key:{0}_{1}_{2}", CacheConst.HotelTask, task.Hotelid, "isRun"));
                }
                 
            }
            catch (Exception ex)
            {
                StateMonitorholder.WirteErrorLog(((TaskDefine)p).Hotelid, ex.Message);
                LogHelper.GetErrorLog().Debug(ex);
            }

        }
       
        protected virtual void AddQueue(TaskDefine task)
        {
            if (queueDict.ContainsKey(task.Hotelid))
            {
                Queue<TaskDefine> queue_ = queueDict[task.Hotelid];
                if (queue_ == null)
                    queue_ = new Queue<TaskDefine>();

                queue_.Enqueue(task);
            }
            else
            {

                queueDict[task.Hotelid] = new Queue<TaskDefine>();
                queueDict[task.Hotelid].Enqueue(task);
            }
        }

        protected virtual void ExecuteQueue(Queue<TaskDefine> queue)
        {
            
            while (queue.Count != 0)
            {
                             
                    try
                    {
                        LogHelper.GetDebugLog().Debug(string.Format("while queue count:{0}", queue.Count));
                        if (queue.Count == 0)
                            break;

                        TaskDefine obj= queue.Dequeue();
                        WebServiceParam Param = GetWsParam(obj);
                        LogHelper.GetDebugLog().Debug(string.Format("Dequeue queue count:{0},{1},{2}", queue.Count, obj.Hotelid, Param.DataSource));
                        DataSet ds = TransferHolder.GetData(Param) as DataSet;
                        if (ds.Tables.Count > 0)
                        {
                            LogHelper.GetDebugLog().Debug(string.Format("dataset count:{0},{1},Dequeue queue count:{2}", ds.Tables[0].Rows.Count, obj.Hotelid, queue.Count));
                            LogHelper.GetDebugLog().Debug("end tranfer");

                            LogHelper.GetDebugLog().Debug("begin save data");
                            ActionBusinessHolder.Save(ds, obj.PrimaryKey, obj.CenterTableName, obj.IsUpdate);

                            LogHelper.GetDebugLog().Debug("begin save data");
                        }
                        else 
                        {
                            LogHelper.GetDebugLog().Debug("Not data transfer");
                        }
                    }
                    catch (Exception ex)
                    {
                        StateMonitorholder.WirteErrorLog("xx", ex.Message);
                        LogHelper.GetErrorLog().Debug(ex);

                    }
                
            }
           
        }
        public bool GetState()
        {
            return false;
        }
        public Dictionary<string, Queue<TaskDefine>> GetQueue()
        {
            Dictionary<string, Queue<TaskDefine>> dict = new Dictionary<string, Queue<TaskDefine>>();
            return dict;
        }
        
        private WebServiceParam GetWsParam(TaskDefine task)
        {
            WebServiceParam Param = new WebServiceParam();
           
            Param.Url = task.Interface;

            
            string DataSource = task.DataSource;

            DataSource = Replace(DataSource,task.MacroDict);


            Param.DataSource = DataSource;

            return Param;
        }

        private string Replace(string DataSource,Dictionary<string,string> dict)
        {           
            DataSource = TransfersMacro.GetMacro(DataSource);
            if (dict != null)
            {
                foreach (string key in dict.Keys)
                {
                    string Expressions = "(\\$\\{" + key + "\\})";
                    Regex reg = new Regex(Expressions);
                    DataSource = reg.Replace(DataSource, dict[key]);

                }
            }
            LogHelper.GetDebugLog().Debug(string.Format("DataSource:{0}", DataSource));
            return DataSource;
        }
         
        #endregion
    }
}
